#include "ComProtocol.h"

Com_Message_struct Com_Message_Tx;										//Struct which contains data of the next message to be transmitted
Com_Message_struct Com_Message_Rx;										//Struct which contains data of the last received message

/*
Fill message struct with data
This Procedure has to be called before caling Com_Message_Tx_send
*/

void Com_Message_Tx_create(uint8_t id, uint8_t dlc, uint8_t *data)
{
	uint8_t loopcntr = 0;

	Com_Message_Tx.id  = id;
	Com_Message_Tx.dlc = dlc;

	for(loopcntr=0; loopcntr<dlc; loopcntr++)
	{
		Com_Message_Tx.data[loopcntr] = *(data+loopcntr);
	}
}

/*
Trigger the transmission of the message, which was created before
Call this procedure after calling Com_Message_Tx_create
*/

void Com_Message_Tx_send(void)
{
	uint8_t loopcntr = 0;

	uart_putc(SOF);
	uart_putc(SYNC);
	uart_putc(Com_Message_Tx.id);
	uart_putc(Com_Message_Tx.dlc);

	for(loopcntr=0; loopcntr<Com_Message_Tx.dlc; loopcntr++)
		uart_putc(Com_Message_Tx.data[loopcntr]);
}


/*
This procedure is called every time after one character was received from UART
It contains the algorithm to fill Com_Message_Rx after one message was received completely and successful
After filling the struct depending on the id the correponding message process routine is called
*/

uint16_t temp;
uint8_t out;

void Com_Message_Rx_process(void)
{

	static uint8_t state;
	static uint8_t data_bytes_to_read;
	uint8_t i;

	while ((temp = uart_getc())!= UART_NO_DATA){

		if(temp&0xFF00)
			return;
		else
			temp &= 0x00FF;

		out = (uint8_t)temp;
		printf(" %c \n", out);

	}

	switch(state)
	{
		case UNKNOWN:
			if(temp == SOF)
				state = SOF_RECEIVED;
			break;
		case SOF_RECEIVED:
			if(temp == SYNC)
				state = SYNC_RECEIVED;
			else
				state = UNKNOWN;
			break;
		case SYNC_RECEIVED:
			Com_Message_Rx.id = (uint8_t)temp;
			state = ID_RECEIVED;
			break;
		case ID_RECEIVED:
			Com_Message_Rx.dlc = (uint8_t)temp;
			state = DLC_RECEIVED;
			data_bytes_to_read = Com_Message_Rx.dlc;
			if(data_bytes_to_read == 0)
				state = EOF;
			break;
		case DLC_RECEIVED:
			Com_Message_Rx.data[Com_Message_Rx.dlc - data_bytes_to_read] = (uint8_t)temp;
			data_bytes_to_read--;
			if(data_bytes_to_read == 0)
				state = EOF;
			break;
		default:
			state = UNKNOWN;
			break;
	}

	if(state == EOF)
	{
		switch(Com_Message_Rx.id)
		{
			case PC_ID_REQ_DATA:
				Com_Message_Tx_create(MC_ID_SEND_DATA, sizeof(S_DATA), (uint8_t*)&s_data);
				Com_Message_Tx_send();
				break;
			case PC_ID_SEND_DATE:
#ifndef DEBUG_SERVER
				RTC_processRxData();
#endif
				Com_Message_Tx_create(MC_ID_SEND_DATA, sizeof(S_DATA), (uint8_t*)&s_data);
				Com_Message_Tx_send();
				break;
			case PC_ID_SEND_SUT_DATE:
#ifndef DEBUG_SERVER
				RTC_processSutData();
#endif
				Com_Message_Tx_create(MC_ID_SEND_DATA, sizeof(S_DATA), (uint8_t*)&s_data);
				Com_Message_Tx_send();
				break;
			case PC_ID_SEND_DATA:
				for(i=0; i < sizeof(S_SEND_DATA); i++)
					((uint8_t*)&s_data)[i] = Com_Message_Rx.data[i];

				Com_Message_Tx_create(MC_ID_SEND_DATA, sizeof(S_DATA), (uint8_t*)&s_data);
				Com_Message_Tx_send();
				break;
			default:
				break;
		}
		state = UNKNOWN;
		Com_Message_Rx.id = 0xFF;
	}

}
